<!DOCTYPE HTML>
<html lang="zh-CN">


<head>
    <meta charset="utf-8">
    <meta name="keywords" content="Java中的集合Collection和Map, 大虫のBlog">
    <meta name="description" content="电子科技大学 | 信软学院 | 软件工程">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="renderer" content="webkit|ie-stand|ie-comp">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <!-- Global site tag (gtag.js) - Google Analytics -->


    <title>Java中的集合Collection和Map | 大虫のBlog</title>
    <link rel="icon" type="image/png" href="/favicon.png">

    <link rel="stylesheet" type="text/css" href="/libs/awesome/css/all.css">
    <link rel="stylesheet" type="text/css" href="/libs/materialize/materialize.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/aos/aos.css">
    <link rel="stylesheet" type="text/css" href="/libs/animate/animate.min.css">
    <link rel="stylesheet" type="text/css" href="/libs/lightGallery/css/lightgallery.min.css">
    <link rel="stylesheet" type="text/css" href="/css/matery.css">
    <link rel="stylesheet" type="text/css" href="/css/my.css">

    <script src="/libs/jquery/jquery.min.js"></script>

<meta name="generator" content="Hexo 6.2.0"></head>




<body>
    <header class="navbar-fixed">
    <nav id="headNav" class="bg-color nav-transparent">
        <div id="navContainer" class="nav-wrapper container">
            <div class="brand-logo">
                <a href="/" class="waves-effect waves-light">
                    
                    <img src="/medias/logo.png" class="logo-img" alt="LOGO">
                    
                    <span class="logo-span">大虫のBlog</span>
                </a>
            </div>
            

<a href="#" data-target="mobile-nav" class="sidenav-trigger button-collapse"><i class="fas fa-bars"></i></a>
<ul class="right nav-menu">
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/" class="waves-effect waves-light">
      
      <i class="fas fa-home" style="zoom: 0.6;"></i>
      
      <span>首页</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/tags" class="waves-effect waves-light">
      
      <i class="fas fa-tags" style="zoom: 0.6;"></i>
      
      <span>标签</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/categories" class="waves-effect waves-light">
      
      <i class="fas fa-bookmark" style="zoom: 0.6;"></i>
      
      <span>分类</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/archives" class="waves-effect waves-light">
      
      <i class="fas fa-archive" style="zoom: 0.6;"></i>
      
      <span>归档</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/about" class="waves-effect waves-light">
      
      <i class="fas fa-user-circle" style="zoom: 0.6;"></i>
      
      <span>关于</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/contact" class="waves-effect waves-light">
      
      <i class="fas fa-comments" style="zoom: 0.6;"></i>
      
      <span>留言板</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/friends" class="waves-effect waves-light">
      
      <i class="fas fa-address-book" style="zoom: 0.6;"></i>
      
      <span>友情链接</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="" class="waves-effect waves-light">

      
      <i class="fa fa-list" style="zoom: 0.6;"></i>
      
      <span>其他</span>
      <i class="fas fa-chevron-down" aria-hidden="true" style="zoom: 0.6;"></i>
    </a>
    <ul class="sub-nav menus_item_child ">
      
      <li>
        <a target="_blank" rel="noopener" href="https://console.leancloud.cn">
          
          <i class="fa-solid fa-link" style="margin-top: -20px; zoom: 0.6;"></i>
          
          <span>LeanCloud 应用</span>
        </a>
      </li>
      
      <li>
        <a target="_blank" rel="noopener" href="https://www.tidio.com/panel">
          
          <i class="fa-solid fa-link" style="margin-top: -20px; zoom: 0.6;"></i>
          
          <span>TIDIO 聊天系统</span>
        </a>
      </li>
      
      <li>
        <a target="_blank" rel="noopener" href="https://www.coderutil.com">
          
          <i class="fa-solid fa-link" style="margin-top: -20px; zoom: 0.6;"></i>
          
          <span>CoderUtil 工具</span>
        </a>
      </li>
      
    </ul>
    
  </li>
  
  <li>
    <a href="#searchModal" class="modal-trigger waves-effect waves-light">
      <i id="searchIcon" class="fas fa-search" title="搜索" style="zoom: 0.85;"></i>
    </a>
  </li>
</ul>


<div id="mobile-nav" class="side-nav sidenav">

    <div class="mobile-head bg-color">
        
        <img src="/medias/logo.png" class="logo-img circle responsive-img">
        
        <div class="logo-name">大虫のBlog</div>
        <div class="logo-desc">
            
            电子科技大学 | 信软学院 | 软件工程
            
        </div>
    </div>

    

    <ul class="menu-list mobile-menu-list">
        
        <li class="m-nav-item">
	  
		<a href="/" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-home"></i>
			
			首页
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/tags" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-tags"></i>
			
			标签
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/categories" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-bookmark"></i>
			
			分类
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/archives" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-archive"></i>
			
			归档
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/about" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-user-circle"></i>
			
			关于
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/contact" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-comments"></i>
			
			留言板
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/friends" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-address-book"></i>
			
			友情链接
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="javascript:;">
			
				<i class="fa-fw fa fa-list"></i>
			
			其他
			<span class="m-icon"><i class="fas fa-chevron-right"></i></span>
		</a>
            <ul  style="background:  ;" >
              
                <li>

                  <a target="_blank" rel="noopener" href="https://console.leancloud.cn " style="margin-left:75px">
				  
				   <i class="fa fa-solid fa-link" style="position: absolute;left:50px" ></i>
			      
		          <span>LeanCloud 应用</span>
                  </a>
                </li>
              
                <li>

                  <a target="_blank" rel="noopener" href="https://www.tidio.com/panel " style="margin-left:75px">
				  
				   <i class="fa fa-solid fa-link" style="position: absolute;left:50px" ></i>
			      
		          <span>TIDIO 聊天系统</span>
                  </a>
                </li>
              
                <li>

                  <a target="_blank" rel="noopener" href="https://www.coderutil.com " style="margin-left:75px">
				  
				   <i class="fa fa-solid fa-link" style="position: absolute;left:50px" ></i>
			      
		          <span>CoderUtil 工具</span>
                  </a>
                </li>
              
            </ul>
          
        </li>
        
        
        <li><div class="divider"></div></li>
        <li>
            <a href="https://gitee.com/yczlab" class="waves-effect waves-light" target="_blank">
                <i class="fab fa-github-square fa-fw"></i>Fork Me
            </a>
        </li>
        
    </ul>
</div>


        </div>

        
            <style>
    .nav-transparent .github-corner {
        display: none !important;
    }

    .github-corner {
        position: absolute;
        z-index: 10;
        top: 0;
        right: 0;
        border: 0;
        transform: scale(1.1);
    }

    .github-corner svg {
        color: #0f9d58;
        fill: #fff;
        height: 64px;
        width: 64px;
    }

    .github-corner:hover .octo-arm {
        animation: a 0.56s ease-in-out;
    }

    .github-corner .octo-arm {
        animation: none;
    }

    @keyframes a {
        0%,
        to {
            transform: rotate(0);
        }
        20%,
        60% {
            transform: rotate(-25deg);
        }
        40%,
        80% {
            transform: rotate(10deg);
        }
    }
</style>

<a href="https://gitee.com/yczlab" class="github-corner tooltipped hide-on-med-and-down" target="_blank"
   data-tooltip="Fork Me" data-position="left" data-delay="50">
    <svg viewBox="0 0 250 250" aria-hidden="true">
        <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
        <path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
              fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
        <path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
              fill="currentColor" class="octo-body"></path>
    </svg>
</a>
        
    </nav>

</header>

    



<div class="bg-cover pd-header post-cover" style="background-image: url('/medias/featureimages/23.jpg')">
    <div class="container" style="right: 0px;left: 0px;">
        <div class="row">
            <div class="col s12 m12 l12">
                <div class="brand">
                    <h1 class="description center-align post-title">Java中的集合Collection和Map</h1>
                </div>
            </div>
        </div>
    </div>
</div>




<main class="post-container content">

    
    <link rel="stylesheet" href="/libs/tocbot/tocbot.css">
<style>
    #articleContent h1::before,
    #articleContent h2::before,
    #articleContent h3::before,
    #articleContent h4::before,
    #articleContent h5::before,
    #articleContent h6::before {
        display: block;
        content: " ";
        height: 100px;
        margin-top: -100px;
        visibility: hidden;
    }

    #articleContent :focus {
        outline: none;
    }

    .toc-fixed {
        position: fixed;
        top: 64px;
    }

    .toc-widget {
        width: 345px;
        padding-left: 20px;
    }

    .toc-widget .toc-title {
        padding: 35px 0 15px 17px;
        font-size: 1.5rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    .toc-widget ol {
        padding: 0;
        list-style: none;
    }

    #toc-content {
        padding-bottom: 30px;
        overflow: auto;
    }

    #toc-content ol {
        padding-left: 10px;
    }

    #toc-content ol li {
        padding-left: 10px;
    }

    #toc-content .toc-link:hover {
        color: #42b983;
        font-weight: 700;
        text-decoration: underline;
    }

    #toc-content .toc-link::before {
        background-color: transparent;
        max-height: 25px;

        position: absolute;
        right: 23.5vw;
        display: block;
    }

    #toc-content .is-active-link {
        color: #42b983;
    }

    #floating-toc-btn {
        position: fixed;
        right: 15px;
        bottom: 76px;
        padding-top: 15px;
        margin-bottom: 0;
        z-index: 998;
    }

    #floating-toc-btn .btn-floating {
        width: 48px;
        height: 48px;
    }

    #floating-toc-btn .btn-floating i {
        line-height: 48px;
        font-size: 1.4rem;
    }
</style>
<div class="row">
    <div id="main-content" class="col s12 m12 l9">
        <!-- 文章内容详情 -->
<div id="artDetail">
    <div class="card">
        <div class="card-content article-info">
            <div class="row tag-cate">
                <div class="col s7">
                    
                    <div class="article-tag">
                        
                            <a href="/tags/Java/">
                                <span class="chip bg-color">Java</span>
                            </a>
                        
                    </div>
                    
                </div>
                <div class="col s5 right-align">
                    
                    <div class="post-cate">
                        <i class="fas fa-bookmark fa-fw icon-category"></i>
                        
                            <a href="/categories/Java/" class="post-category">
                                Java
                            </a>
                        
                    </div>
                    
                </div>
            </div>

            <div class="post-info">
                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-minus fa-fw"></i>发布日期:&nbsp;&nbsp;
                    2021-01-09
                </div>
                

                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-check fa-fw"></i>更新日期:&nbsp;&nbsp;
                    2022-07-31
                </div>
                

                
                <div class="info-break-policy">
                    <i class="far fa-file-word fa-fw"></i>文章字数:&nbsp;&nbsp;
                    9.9k
                </div>
                

                
                <div class="info-break-policy">
                    <i class="far fa-clock fa-fw"></i>阅读时长:&nbsp;&nbsp;
                    38 分
                </div>
                

                
                    <div id="busuanzi_container_page_pv" class="info-break-policy">
                        <i class="far fa-eye fa-fw"></i>阅读次数:&nbsp;&nbsp;
                        <span id="busuanzi_value_page_pv"></span>
                    </div>
				
            </div>
        </div>
        <hr class="clearfix">

        
        <!-- 是否加载使用自带的 prismjs. -->
        <link rel="stylesheet" href="/libs/prism/prism.css">
        

        

        <div class="card-content article-card-content">
            <div id="articleContent">
                <p>  </p>
<h2 id="引言："><a href="#引言：" class="headerlink" title="引言："></a>引言：</h2><blockquote>
<p>Java中的集合可分为 <strong>Collection</strong> 和 <strong>Map</strong> 两种体系。Collection接口：单列数据，定义了存取一组对象的方法的集合。Map接口：双列数据，保存具有映射关系“key-value对”的集合。Java 集合类可以用于<strong>存储数量不等的多个对象</strong>，还可用于<strong>保存具有映射关系的关联数组</strong>。Java 集合就像一种<strong>容器</strong>，可以动态地把多个对象的引用放入容器中。</p>
</blockquote>
<h3 id="一、数组的特点和弊端"><a href="#一、数组的特点和弊端" class="headerlink" title="一、数组的特点和弊端"></a>一、数组的特点和弊端</h3><ol>
<li><p>数组在内存存储方面的特点：</p>
<blockquote>
<ul>
<li>数组初始化以后，长度就确定了。</li>
<li>数组声明的类型，就决定了进行元素初始化时的类型。数组一旦定义好，其元素的类型也就确定了。我们也就只能操作指定类型的数据了。</li>
</ul>
</blockquote>
</li>
<li><p>数组在存储数据方面的弊端：</p>
<blockquote>
<ul>
<li>数组初始化以后，长度就不可变了，不便于扩展</li>
<li>数组中提供的属性和方法少，不便于进行添加、删除、插入等操作，且效率不高。</li>
<li>获取数组中实际元素的个数的需求，数组没有现成的属性或方法可用</li>
<li>数组存储数据的特点：有序、可重复。对于无序、不可重复的需求，不能满足。（存储数据的特点单一）</li>
</ul>
</blockquote>
</li>
</ol>
<h3 id="二、java中的集合框架（API）"><a href="#二、java中的集合框架（API）" class="headerlink" title="二、java中的集合框架（API）"></a>二、java中的集合框架（API）</h3><p><strong>1. Collection接口：单列集合，用来存储一个一个的对象</strong></p>
<blockquote>
<ul>
<li><p><strong>List接口：存储有序的、可重复的数据。（更像是动态的数组）</strong></p>
<blockquote>
<p><strong>ArrayList、LinkedList、Vector</strong></p>
</blockquote>
</li>
<li><p><strong>Set接口：存储无序的、不可重复的数据。（更像是数学中的集合）</strong></p>
<blockquote>
<p><strong>HashSet、LinkedHashSet、TreeSet</strong></p>
</blockquote>
</li>
</ul>
<p><img src="/posts/b593f441/1.png" alt="Collection接口继承树"></p>
</blockquote>
<p><strong>2. Map接口：双列集合，用来存储一对一对（key-value）的数据</strong></p>
<blockquote>
<ul>
<li><strong>HashMap、LinkedHashMap、TreeMap、Hashtable、Properties</strong><br><img src="/posts/b593f441/2.png" alt="Map接口继承树"></li>
</ul>
</blockquote>
<h3 id="三、Cellection接口"><a href="#三、Cellection接口" class="headerlink" title="三、Cellection接口"></a>三、Cellection接口</h3><p>  Collection 接口是 List、Set 和 Queue 接口的<strong>父接口</strong>，该接口里定义的方法既可用于操作 Set 集合，也可用于操作 List 和 Queue 集合。<strong>JDK不提供此接口的任何直接实现</strong>，而是提供更具体的子接口(如：Set和List)实现。在 Java5 之前，Java 集合会丢失容器中所有对象的数据类型，把所有对象都当成 Object 类型处理；从 JDK 5.0 增加了<strong>泛型</strong>以后，Java 集合可以记住容器中对象的数据类型。集合Collection中存储的如果是自定义类的对象，需要自定义类重写equals()方法。</p>
<h4 id="1、Collection接口中的常用方法"><a href="#1、Collection接口中的常用方法" class="headerlink" title="1、Collection接口中的常用方法"></a>1、Collection接口中的常用方法</h4><blockquote>
<ul>
<li>1.添加<blockquote>
<p><strong>add(Object obj)</strong><br><strong>addAll(Collection coll)</strong></p>
</blockquote>
</li>
<li>2.获取有效元素个数：<strong>int size()</strong></li>
<li>3.清空集合：<strong>void clear()</strong></li>
<li>4.判断是否是空集合：<strong>boolean isEmpty()</strong></li>
<li>5.判断是否包含某个元素<blockquote>
<ul>
<li><strong>boolean contains(Object obj)：</strong>是通过元素的equals()方法来判断是否是同一个对象。<strong>将集合中的元素依次作为obj.equals()方法的形参</strong>。</li>
<li><strong>boolean containsAll(Collection c)：</strong>判断形参集合c中的所有元素是否都存在于当前集合中。<strong>依次遍历形参集合c中的元素obj，然后将调用者集合中的元素依次作为obj.equals()方法的形参来进行判断。</strong>相当于形参集合c中的每个元素都要挨个与调用者集合中的每个元素进行判断（最坏的情况下）。</li>
</ul>
</blockquote>
</li>
<li>6.删除<blockquote>
<ul>
<li><strong>boolean remove(Object obj)：</strong>通过元素的equals()方法判断是否是要删除的那个元素。<strong>只会删除找到的第一个元素</strong>。</li>
<li><strong>boolean removeAll(Collection coll)：</strong> <strong>取当前集合的差集</strong></li>
</ul>
</blockquote>
</li>
<li>7.取两个集合的交集：<strong>boolean retainAll(Collection c)：</strong>把交集的结果存在当前集合中，不影响c</li>
<li>8.集合是否相等：<strong>boolean equals(Object obj)</strong> 当前集合和形参集合的元素都相同时，返回true。</li>
<li>9.转换成对象数组：<strong>Object[] toArray()</strong></li>
<li>10.获取集合对象的哈希值：<strong>hashCode()</strong></li>
<li>11.遍历：<strong>iterator()：</strong>返回迭代器对象，用于遍历集合元素</li>
</ul>
</blockquote>
<h4 id="2、使用-Iterator-接口遍历Collection集合元素"><a href="#2、使用-Iterator-接口遍历Collection集合元素" class="headerlink" title="2、使用 Iterator 接口遍历Collection集合元素"></a>2、使用 Iterator 接口遍历Collection集合元素</h4><ol>
<li>Iterator对象称为迭代器(设计模式的一种)，主要用于遍历 Collection 集合中的元素<strong>。注：不适用遍历Map集合</strong>。</li>
<li>提供一种方法访问一个容器(container)对象中各个元素，而又<strong>不需暴露该对象的内部细节</strong>。迭代器模式，就是为容器而生。</li>
<li>Collection接口继承了java.lang.Iterable接口，该接口有一个iterator()方法，那么所有实现了Collection接口的集合类都有一个iterator()方法，用以<strong>返回一个实现了Iterator接口的对象</strong>。</li>
<li>Iterator 仅用于遍历集合，Iterator <strong>本身并不提供承装对象的能力</strong>。如果需要创建Iterator 对象，则必须有一个被迭代的集合。</li>
<li>集合对象每次调用iterator()方法都得到一个<strong>全新的迭代器对象</strong>，默认游标都在集合的第一个元素之前。</li>
<li>内部定义了remove(),可以在遍历的时候，删除集合中的元素。此方法不同于集合直接调用remove()。如果<strong>还未调用过next()<strong>或在上一次调用 next 方法之后已经调用了remove 方法，再调用remove都会报</strong>IllegalStateException</strong>异常。</li>
<li>在调用it.next()方法之前必须要调用it.hasNext()进行检测。若不调用，且下一条记录无效，直接调用it.next()会抛出<strong>NoSuchElementException</strong>异常。<br><img src="/posts/b593f441/3.png"><pre class="language-java" data-language="java"><code class="language-java"><span class="token comment">/*Iterator遍历集合的正确使用*/</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">IteratorTest</span> <span class="token punctuation">&#123;</span>
    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token class-name">Collection</span> coll <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        coll<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">123</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        coll<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">456</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        coll<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token string">"Jerry"</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        coll<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">String</span><span class="token punctuation">(</span><span class="token string">"Tom"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        coll<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token class-name">Iterator</span> iterator <span class="token operator">=</span> coll<span class="token punctuation">.</span><span class="token function">iterator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">/*方式一：*/</span>
        <span class="token comment">/*
        System.out.println(iterator.next());
        System.out.println(iterator.next());
        System.out.println(iterator.next());
        System.out.println(iterator.next());
        System.out.println(iterator.next());
        System.out.println(iterator.next());//报异常：NoSuchElementException
        */</span>

        <span class="token comment">/*方式二：不推荐这样使用*/</span>
        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> coll<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>iterator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"********************"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        iterator <span class="token operator">=</span> coll<span class="token punctuation">.</span><span class="token function">iterator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//重新赋值</span>
        <span class="token comment">/*方式三：推荐使用*/</span>
        <span class="token comment">//hasNext()：判断是否还有下一个元素</span>
        <span class="token keyword">while</span> <span class="token punctuation">(</span>iterator<span class="token punctuation">.</span><span class="token function">hasNext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>iterator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//next()：①指针下移 ②将下移以后集合位置上的元素返回</span>
        <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre></li>
</ol>
<h4 id="3、使用foreach循环（增强for循环）遍历集合元素"><a href="#3、使用foreach循环（增强for循环）遍历集合元素" class="headerlink" title="3、使用foreach循环（增强for循环）遍历集合元素"></a>3、使用foreach循环（增强for循环）遍历集合元素</h4><ol>
<li>Java 5.0 提供了 foreach 循环迭代访问 Collection和数组。</li>
<li>遍历操作不需获取Collection或数组的长度，无需使用索引访问元素。</li>
<li><strong>遍历集合的底层调用Iterator完成操作</strong>。</li>
<li>foreach还可以用来遍历数组。<pre class="language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ForTest</span> <span class="token punctuation">&#123;</span>
    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test1</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token class-name">Collection</span> coll <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        coll<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">123</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        coll<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">456</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        coll<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token string">"Jerry"</span><span class="token punctuation">,</span> <span class="token number">20</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        coll<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">String</span><span class="token punctuation">(</span><span class="token string">"Tom"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        coll<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment">//for(集合元素的类型 局部变量 : 集合对象)</span>
        <span class="token comment">//内部仍然调用了迭代器</span>
        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">Object</span> obj <span class="token operator">:</span> coll<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test2</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">int</span><span class="token punctuation">[</span><span class="token punctuation">]</span> arr <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token keyword">int</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">&#123;</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
        <span class="token comment">//for(数组元素的类型 局部变量 : 数组对象)</span>
        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">int</span> i <span class="token operator">:</span> arr<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>

        <span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> arr2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">&#123;</span><span class="token string">"AA"</span><span class="token punctuation">,</span> <span class="token string">"BB"</span><span class="token punctuation">,</span> <span class="token string">"CC"</span><span class="token punctuation">&#125;</span><span class="token punctuation">;</span>
        <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name">String</span> s <span class="token operator">:</span> arr2<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            s <span class="token operator">=</span> <span class="token string">"DD"</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token class-name">Arrays</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span>arr2<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//[AA, BB, CC]</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre></li>
</ol>
<h3 id="四、Collection的子接口-之-List-接口"><a href="#四、Collection的子接口-之-List-接口" class="headerlink" title="四、Collection的子接口 之 List 接口"></a>四、Collection的子接口 之 List 接口</h3><p>  鉴于Java中数组用来存储数据的局限性，我们通常使用List替代数组。List集合类中<strong>元素有序、且可重复</strong>，集合中的每个元素都有其对应的顺序索引。List容器中的元素都对应一个整数型的序号记载其在容器中的位置，可以根据序号存取容器中的元素。JDK API中List接口的实现类常用的有：<strong>ArrayList</strong>、<strong>LinkedList</strong>和<strong>Vector</strong>。</p>
<blockquote>
<ul>
<li><strong>ArrayList：</strong>作为List接口的<strong>主要实现类</strong>（JDK1.2）；<strong>线程不安全的，效率高</strong>；底层使用Object[] elementData存储</li>
<li><strong>LinkedList：</strong>（JDK1.2）对于<strong>频繁的插入、删除</strong>操作，使用此类<strong>效率比ArrayList高</strong>；底层使用<strong>双向链表</strong>存储</li>
<li><strong>Vector：</strong>作为List接口的<strong>古老实现类</strong>（JDK1.0）；<strong>线程安全的，效率低</strong>；底层使用Object[] elementData存储</li>
</ul>
</blockquote>
<p>  <strong>注意：</strong>Arrays.asList(T… a) 方法返回的 List 集合，既不是 ArrayList 实例，也不是Vector 实例。 Arrays.asList(T… a) 返回值是一个固定长度的 List 集合，Arrays类中有一个内部类private static class ArrayList&lt;E&gt; extends AbstractList&lt;E&gt; implements RandomAccess, java.io.Serializable。</p>
<h4 id="1、List接口中的常用方法"><a href="#1、List接口中的常用方法" class="headerlink" title="1、List接口中的常用方法"></a>1、List接口中的常用方法</h4><p>  List除了从Collection集合继承的方法外，List 集合里添加了一些根据索引来操作集合元素的方法。</p>
<blockquote>
<ul>
<li><strong>void add(int index, Object ele)：</strong>在index位置插入ele元素</li>
<li><strong>boolean addAll(int index, Collection eles)：</strong>从index位置开始将eles中的所有元素添加进来</li>
<li><strong>Object get(int index)：</strong>获取指定index位置的元素</li>
<li><strong>int indexOf(Object obj)：</strong>返回obj在集合中首次出现的位置。不存在时，返回-1</li>
<li><strong>int lastIndexOf(Object obj)：</strong>返回obj在当前集合中末次出现的位置。不存在时，返回-1</li>
<li><strong>Object remove(int index)：</strong>移除指定index位置的元素，并返回此元素</li>
<li><strong>Object set(int index, Object ele)：</strong>设置指定index位置的元素为ele</li>
<li><strong>List subList(int fromIndex, int toIndex)：</strong>返回从fromIndex到toIndex 位置的子集合</li>
<li><strong>总结：</strong><blockquote>
<ul>
<li>增：add(Object obj)</li>
<li>删：remove(int index) &#x2F; remove(Object obj)</li>
<li>改：set(int index, Object ele)</li>
<li>查：get(int index)</li>
<li>插：add(int index, Object ele)</li>
<li>长度：size()</li>
<li>遍历：① Iterator迭代器方式; ② 增强for循环; ③ 普通的循环（因为其具有索引）</li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
<h4 id="2、ArrayList-类"><a href="#2、ArrayList-类" class="headerlink" title="2、ArrayList 类"></a>2、ArrayList 类</h4><p>  ArrayList 是 List 接口的典型实现类、主要实现类。本质上，<strong>ArrayList是对象引用的一个”变长”数组</strong>。</p>
<h5 id="jdk-7-的情况"><a href="#jdk-7-的情况" class="headerlink" title="jdk 7 的情况"></a>jdk 7 的情况</h5><p>  ArrayList像饿汉式，直接创建一个<strong>初始容量为10</strong>的数组。</p>
<ul>
<li>ArrayList list &#x3D; new ArrayList();&#x2F;&#x2F;底层创建了<strong>长度是10</strong>的Object[]数组elementData</li>
<li>list.add(123);&#x2F;&#x2F;elementData[0] &#x3D; new Integer(123);</li>
<li>…</li>
<li>list.add(11);&#x2F;&#x2F;如果此次的添加导致底层elementData数组容量不够，则扩容。</li>
<li>默认情况下，<strong>扩容为原来的容量的1.5倍</strong>，同时需要将原有数组中的数据复制到新的数组中。</li>
<li>结论：建议开发中使用带参的构造器：ArrayList list &#x3D; new ArrayList(int capacity)</li>
</ul>
<h5 id="jdk-8-的变化"><a href="#jdk-8-的变化" class="headerlink" title="jdk 8 的变化"></a>jdk 8 的变化</h5><p>  ArrayList像懒汉式，一开始创建一个<strong>长度为0</strong>的数组，当添加第一个元素时再创建一个始容量为10的数组</p>
<ul>
<li>ArrayList list &#x3D; new ArrayList();&#x2F;&#x2F;底层Object[] elementData初始化为{}。并没有创建长度为10的数组</li>
<li>list.add(123);&#x2F;&#x2F;第一次调用add()时，底层才创建了<strong>长度10</strong>的数组，并将数据123添加到elementData[0]</li>
<li>…</li>
<li>后续的添加和扩容操作与jdk 7 无异。</li>
</ul>
<h5 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h5><p>  jdk7中的ArrayList的对象的创建类似于单例的饿汉式，而jdk8中的ArrayList的对象的创建类似于单例的懒汉式，延迟了数组的创建，节省内存。</p>
<h4 id="3、LinkedList-类"><a href="#3、LinkedList-类" class="headerlink" title="3、LinkedList 类"></a>3、LinkedList 类</h4><p>  对于频繁的插入或删除元素的操作，建议使用LinkedList类，效率较高。LinkedList：<strong>双向链表</strong>，内部没有声明数组，而是定义了Node类型的 <strong>first</strong> 和 <strong>last</strong>，用于记录首末元素。同时，定义<strong>内部类Node</strong>，作为LinkedList中保存数据的基本结构。Node除了保存数据，还定义了两个变量：① <strong>prev</strong>变量记录前一个元素的位置；② <strong>next</strong>变量记录下一个元素的位置。</p>
<h5 id="源码分析"><a href="#源码分析" class="headerlink" title="源码分析"></a>源码分析</h5><ul>
<li>LinkedList list &#x3D; new LinkedList(); 内部声明了Node类型的first和last属性，默认值为null</li>
<li>list.add(123);&#x2F;&#x2F;将123封装到Node中，创建了Node对象。</li>
<li>其中，Node定义如下，体现了LinkedList的双向链表的说法<br><img src="/posts/b593f441/4.png" alt="双向链表结构"></li>
</ul>
<h5 id="新增方法"><a href="#新增方法" class="headerlink" title="新增方法"></a>新增方法</h5><blockquote>
<ul>
<li><strong>void addFirst(Object obj)</strong></li>
<li><strong>void addLast(Object obj)</strong></li>
<li><strong>Object getFirst()</strong></li>
<li><strong>Object getLast()</strong></li>
<li><strong>Object removeFirst()</strong></li>
<li><strong>Object removeLast()</strong></li>
</ul>
</blockquote>
<h4 id="4、Vector-类"><a href="#4、Vector-类" class="headerlink" title="4、Vector 类"></a>4、Vector 类</h4><p>  Vector 是一个古老的集合，在JDK 1.0中就有了。大多数操作与ArrayList相同，区别之处在于<strong>Vector是线程安全的</strong>。jdk7和jdk8中通过Vector()构造器创建对象时，底层都创建了长度为10的数组。在扩容方面，默认扩容为原来的数组长度的2倍。</p>
<h5 id="常用方法"><a href="#常用方法" class="headerlink" title="常用方法"></a>常用方法</h5><blockquote>
<ul>
<li><strong>void addElement(Object obj)</strong></li>
<li><strong>void insertElementAt(Object obj,int index)</strong></li>
<li><strong>void setElementAt(Object obj,int index)</strong></li>
<li><strong>void removeElement(Object obj)</strong></li>
<li><strong>void removeElementAt(int index)</strong></li>
<li><strong>void removeAllElements()</strong></li>
</ul>
</blockquote>
<h4 id="5、常见面试题"><a href="#5、常见面试题" class="headerlink" title="5、常见面试题"></a>5、常见面试题</h4><p>  三个类都是实现了List接口，存储数据的特点相同：<strong>存储有序的、可重复的数据</strong><br><strong>1. ArrayList和LinkedList的异同</strong><br>  首先二者都线程不安全，相对线程安全的Vector，执行效率高。此外，ArrayList是实现了基于动态数组的数据结构，LinkedList基于链表的数据结构。对于随机访问get和set，ArrayList绝对优于LinkedList，因为LinkedList要移动指针。对于新增和删除操作add(特指插入)和remove，LinkedList比较占优势，因为ArrayList要移动数据。<br><strong>2. ArrayList和Vector的区别</strong><br>  Vector和ArrayList几乎是完全相同的，唯一的区别在于Vector是同步类(synchronized)，属于强同步类。因此开销就比ArrayList要大，访问要慢。正常情况下，大多数的Java程序员使用ArrayList而不是Vector，因为同步完全可以由程序员自己来控制。Vector每次扩容请求其大小的2倍空间，而ArrayList是1.5倍。<strong>Vector还有一个子类Stack</strong>。<br><strong>3. 迷惑行为</strong></p>
<pre class="language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ListTest</span> <span class="token punctuation">&#123;</span>
    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token class-name">Collection</span> coll <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        coll<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        coll<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        coll<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        coll<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//自动装箱。Collection接口中的remove方法是remove(Object o)，并没有带索引的remove方法，因为其要兼顾Set接口。</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>coll<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//[2, 3]</span>

        <span class="token class-name">List</span> list <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        list<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        list<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        list<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        list<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//List接口中除了remove(Object o)外，还有重载的remove(int index)。因为List有序，其单独定义了一套带索引的操作方法。</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>list<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//[1, 3]</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre>

<h3 id="五、Collection的子接口-之-Set-接口"><a href="#五、Collection的子接口-之-Set-接口" class="headerlink" title="五、Collection的子接口 之 Set 接口"></a>五、Collection的子接口 之 Set 接口</h3><p>  Set 接口是Collection接口的另一个子接口，没有提供额外的方法，其使用的都是Collection中声明过的方法。Set 集合<strong>不允许包含相同的元素</strong>，如果试把两个相同的元素加入同一个Set 集合中，则添加操作失败。Set 判断两个对象是否相同不是使用 “&#x3D;&#x3D;” 运算符，而是根据 equals() 方法。Set接口的实现类用来<strong>存储无序的、不可重复的数据</strong>。Set接口的实现类常用的有<strong>HashSet</strong>、<strong>LinkedHashSet</strong>(直接继承于HashSet)、TreeSet。</p>
<blockquote>
<ul>
<li><strong>HashSet：</strong>作为Set接口的<strong>主要实现类</strong>，是<strong>线程不安全的</strong>，可以存储null值。遍历其内部数据时，并非按照添加的顺序输出。</li>
<li><strong>LinkedHashSet：</strong>做为<strong>HashSet的子类</strong>，遍历其内部数据时，可以按照添加的顺序遍历。对于频繁的遍历操作，LinkedHashSet效率高于HashSet。</li>
<li><strong>TreeSet：</strong>间接实现Set接口，是SortedSet接口的直接实现类，它可以按照添加对象的指定属性，进行排序。</li>
</ul>
</blockquote>
<ol>
<li><strong>无序性：</strong>不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加，而是根据数据的哈希值决定的。</li>
<li><strong>不可重复性：</strong>保证添加的元素按照equals()判断时，不能返回true。即：相同的元素只能添加一个。</li>
</ol>
<p>  向Set（主要指：HashSet、LinkedHashSet）中添加的数据，其所在的类一定要重写hashCode()和equals()。重写的hashCode()和equals()尽可能保持一致性：<strong>相等的对象必须具有相等的散列码</strong>。重写两个方法的小技巧：<strong>对象中用作 equals() 方法比较的 Field，都应该用来计算 hashCode 值</strong>。</p>
<h4 id="1、重写hashCode-方法"><a href="#1、重写hashCode-方法" class="headerlink" title="1、重写hashCode()方法"></a>1、重写hashCode()方法</h4><p>  在程序运行时，同一个对象多次调用 hashCode() 方法应该返回相同的值。当两个对象的 equals() 方法比较返回 true 时，这两个对象的 hashCode()方法的返回值也应相等。对象中用作 equals() 方法比较的 Field，都应该用来计算 hashCode 值。</p>
<pre class="language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token keyword">int</span> age<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token keyword">public</span> <span class="token class-name">User</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">,</span> <span class="token keyword">int</span> age<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>age <span class="token operator">=</span> age<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">return</span> <span class="token string">"User&#123;"</span> <span class="token operator">+</span>
                <span class="token string">"name='"</span> <span class="token operator">+</span> name <span class="token operator">+</span> <span class="token char">'\''</span> <span class="token operator">+</span>
                <span class="token string">", age="</span> <span class="token operator">+</span> age <span class="token operator">+</span>
                <span class="token char">'&#125;'</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">equals</span><span class="token punctuation">(</span><span class="token class-name">Object</span> o<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"User equals()......"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span> <span class="token operator">==</span> o<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>o <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">||</span> <span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> o<span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
        <span class="token class-name">User</span> user <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">User</span><span class="token punctuation">)</span> o<span class="token punctuation">;</span>
        <span class="token keyword">return</span> age <span class="token operator">==</span> user<span class="token punctuation">.</span>age <span class="token operator">&amp;&amp;</span>
                <span class="token class-name">Objects</span><span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span>name<span class="token punctuation">,</span> user<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">hashCode</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">int</span> result <span class="token operator">=</span> name <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">?</span> name<span class="token punctuation">.</span><span class="token function">hashCode</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">;</span>
        result <span class="token operator">=</span> <span class="token number">31</span> <span class="token operator">*</span> result <span class="token operator">+</span> age<span class="token punctuation">;</span>
        <span class="token keyword">return</span> result<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre>
<p><img src="/posts/b593f441/5.png" alt="31这个神奇的数字"></p>
<h4 id="2、重写equals-方法"><a href="#2、重写equals-方法" class="headerlink" title="2、重写equals()方法"></a>2、重写equals()方法</h4><p>  复写equals方法的时候一般都需要同时复写hashCode方法。通常参与计算hashCode的对象的属性也应该参与到equals()中进行计算。</p>
<h4 id="3、HashSet-类"><a href="#3、HashSet-类" class="headerlink" title="3、HashSet 类"></a>3、HashSet 类</h4><p>  HashSet 是 Set 接口的典型实现，大多数时候使用 Set 集合时都使用这个实现类。HashSet 按 <strong>Hash 算法</strong>来存储集合中的元素，因此具有很好的<strong>存取、查找、删除</strong>性能。<strong>JDK7中HashSet底层是数组+链表的结构</strong>。</p>
<h5 id="HashSet-特点"><a href="#HashSet-特点" class="headerlink" title="HashSet 特点"></a>HashSet 特点</h5><blockquote>
<ul>
<li><strong>不能保证元素的排列顺序</strong></li>
<li><strong>HashSet不是线程安全的</strong></li>
<li><strong>集合元素可以是null</strong></li>
</ul>
</blockquote>
<p>  HashSet 集合判断两个元素相等的标准：<strong>两个对象通过 hashCode() 方法比较相等，并且两个对象的 equals() 方法返回值也相等</strong>。对于存放在Set容器中的对象，对应的类一定要重写equals()和hashCode(Object obj)方法，以实现对象相等规则。即：“<strong>相等的对象必须具有相等的散列码</strong>”。</p>
<h5 id="向HashSet中添加元素的过程："><a href="#向HashSet中添加元素的过程：" class="headerlink" title="向HashSet中添加元素的过程："></a>向HashSet中添加元素的过程：</h5><p>  当向 HashSet 集合中存入一个元素时，HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值，然后根据 hashCode 值，通过某种<strong>散列函数</strong>决定该对象在 HashSet <strong>底层数组</strong>中的存储位置。（这个散列函数会与底层数组的长度相计算得到在数组中的下标，即使：索引位置。并且这种散列函数计算出的位置还尽可能地保证能均匀存储元素，越是散列分布，该散列函数设计得越好）。如果两个元素的 hashCode() 值相等，会继续调用 equals() 方法，如果equals方法结果为true，则添加失败；如果为false，那么会保存该元素，但是该数组的位置上已经有元素了，那么会通过<strong>链表的方式</strong>继续链接。如果两个元素的equals()方法返回true，但是他们的hashCode()返回值不相等，HashSet会将他们存储在不同的位置上，也就是说依然可以添加成功，这点很重要，这也是为什么“相等的对象必须具有相等的散列码”的原因。</p>
<blockquote>
<p>  我们向HashSet中添加元素a时，首先调用元素a所在类对象的hashCode()方法，计算元素a的哈希值，此哈希值接着通过某种散列算法计算出在HashSet底层数组中的存放位置（即为：索引位置），判断：数组此位置上是否已经有元素：</p>
<blockquote>
<ul>
<li>如果此位置上没有其他元素，则元素a添加成功。 —&gt;<strong>情况 ①</strong></li>
<li>如果此位置上有其他元素b(或以链表形式存在的多个元素），则比较元素a与元素b的hash值（因为相同hash值会算出相同的位置，不同的hash值也有可能算出相同的位置）：<blockquote>
<ul>
<li>如果hash值不相同，则元素a添加成功。—&gt;<strong>情况 ②</strong></li>
<li>如果hash值相同，进而需要调用元素a所在类的equals()方法：<blockquote>
<ul>
<li>equals()返回true，元素a添加失败</li>
<li>equals()返回false，则元素a添加成功。—&gt;<strong>情况 ③</strong><br><img src="/posts/b593f441/6.png" alt="HashSet底层结构"></li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
<p>  对于添加成功的情况2和情况3而言：元素a与已经存在指定索引位置上数据以链表的方式存储。jdk 7：元素a放到数组中，指向原来的元素。jdk 8：原来的元素在数组中，指向元素a。（七上八下）</p>
</blockquote>
<h5 id="HashSet-的经典例子"><a href="#HashSet-的经典例子" class="headerlink" title="HashSet 的经典例子"></a>HashSet 的经典例子</h5><pre class="language-java" data-language="java"><code class="language-java"><span class="token keyword">class</span> <span class="token class-name">Person</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">int</span> id<span class="token punctuation">;</span>
    <span class="token class-name">String</span> name<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token keyword">int</span> id<span class="token punctuation">,</span> <span class="token class-name">String</span> name<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>id <span class="token operator">=</span> id<span class="token punctuation">;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token keyword">public</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>

    <span class="token punctuation">&#125;</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">return</span> <span class="token string">"Person&#123;"</span> <span class="token operator">+</span>
                <span class="token string">"id="</span> <span class="token operator">+</span> id <span class="token operator">+</span>
                <span class="token string">", name='"</span> <span class="token operator">+</span> name <span class="token operator">+</span> <span class="token char">'\''</span> <span class="token operator">+</span>
                <span class="token char">'&#125;'</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">equals</span><span class="token punctuation">(</span><span class="token class-name">Object</span> o<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span> <span class="token operator">==</span> o<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>o <span class="token operator">==</span> <span class="token keyword">null</span> <span class="token operator">||</span> <span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> o<span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>

        <span class="token class-name">Person</span> person <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">Person</span><span class="token punctuation">)</span> o<span class="token punctuation">;</span>

        <span class="token keyword">if</span> <span class="token punctuation">(</span>id <span class="token operator">!=</span> person<span class="token punctuation">.</span>id<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> name <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">?</span> name<span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span>person<span class="token punctuation">.</span>name<span class="token punctuation">)</span> <span class="token operator">:</span> person<span class="token punctuation">.</span>name <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">hashCode</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token keyword">int</span> result <span class="token operator">=</span> id<span class="token punctuation">;</span>
        result <span class="token operator">=</span> <span class="token number">31</span> <span class="token operator">*</span> result <span class="token operator">+</span> <span class="token punctuation">(</span>name <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">?</span> name<span class="token punctuation">.</span><span class="token function">hashCode</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> result<span class="token punctuation">;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">CollectionTest</span> <span class="token punctuation">&#123;</span>
    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token class-name">HashSet</span> set <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">Person</span> p1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token number">1001</span><span class="token punctuation">,</span><span class="token string">"AA"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">Person</span> p2 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token number">1002</span><span class="token punctuation">,</span><span class="token string">"BB"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        set<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>p1<span class="token punctuation">)</span><span class="token punctuation">;</span>
        set<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span>p2<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>set<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//[Person&#123;id=1002, name='BB'&#125;, Person&#123;id=1001, name='AA'&#125;]</span>

        p1<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"CC"</span><span class="token punctuation">;</span>
        set<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span>p1<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>set<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//[Person&#123;id=1002, name='BB'&#125;, Person&#123;id=1001, name='CC'&#125;]</span>
        set<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token number">1001</span><span class="token punctuation">,</span><span class="token string">"CC"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>set<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//[Person&#123;id=1002, name='BB'&#125;, Person&#123;id=1001, name='CC'&#125;, Person&#123;id=1001, name='CC'&#125;]</span>
        set<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Person</span><span class="token punctuation">(</span><span class="token number">1001</span><span class="token punctuation">,</span><span class="token string">"AA"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>set<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//[Person&#123;id=1002, name='BB'&#125;, Person&#123;id=1001, name='CC'&#125;, Person&#123;id=1001, name='CC'&#125;, Person&#123;id=1001, name='AA'&#125;]</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre>


<h4 id="4、LinkedHashSet-类"><a href="#4、LinkedHashSet-类" class="headerlink" title="4、LinkedHashSet 类"></a>4、LinkedHashSet 类</h4><p>  LinkedHashSet 是 HashSet 的子类。LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置，但它同时使用<strong>双向链表</strong>维护元素的次序，这使得元素看起来是以插入顺序保存的。<strong>LinkedHashSet插入性能略低于 HashSet，因为其在插入元素时会维护一个双向链表</strong>，但在迭代访问 Set 里的全部元素时有很好的性能。LinkedHashSet 也是不允许集合元素重复。<br><img src="/posts/b593f441/7.png" alt="LinkedHashSet底层结构"></p>
<h4 id="5、TreeSet-类"><a href="#5、TreeSet-类" class="headerlink" title="5、TreeSet 类"></a>5、TreeSet 类</h4><p>  TreeSet 是 SortedSet 接口的实现类，TreeSet 可以确保集合元素处于排序状态。TreeSet底层使用<strong>红黑树</strong>结构存储数据。对TreeSet来说重写hashCode()方法不是必须的。TreeSet 两种排序方法：自然排序和定制排序。默认情况下，TreeSet 采用自然排序。</p>
<h5 id="新增的方法（因为其可以确保元素处于排序状态，所以多了一些特殊方法）"><a href="#新增的方法（因为其可以确保元素处于排序状态，所以多了一些特殊方法）" class="headerlink" title="新增的方法（因为其可以确保元素处于排序状态，所以多了一些特殊方法）"></a>新增的方法（因为其可以确保元素处于排序状态，所以多了一些特殊方法）</h5><blockquote>
<ul>
<li>Comparator comparator()</li>
<li>Object first()</li>
<li>Object last()</li>
<li>Object lower(Object e)</li>
<li>Object higher(Object e)</li>
<li>SortedSet subSet(fromElement, toElement)</li>
<li>SortedSet headSet(toElement)</li>
<li>SortedSet tailSet(fromElement)</li>
</ul>
</blockquote>
<h5 id="TreeSet的自然排序"><a href="#TreeSet的自然排序" class="headerlink" title="TreeSet的自然排序"></a>TreeSet的自然排序</h5><p>  TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系，然后将集合元素按升序(默认情况)排列。如果试图把一个对象添加到 TreeSet 时，则该对象的类必须实现 Comparable接口。实现 Comparable 的类必须实现 compareTo(Object obj) 方法，两个对象即通过compareTo(Object obj) 方法的返回值来比较大小。</p>
<blockquote>
<p>Comparable 的典型实现：</p>
<ul>
<li><strong>BigDecimal</strong>、<strong>BigInteger</strong> 以及所有的数值型对应的包装类：按它们对应的数值大小进行比较</li>
<li><strong>Character</strong>：按字符的 unicode值来进行比较</li>
<li><strong>Boolean</strong>：true 对应的包装类实例大于 false 对应的包装类实例</li>
<li><strong>String</strong>：按字符串中字符的 unicode 值进行比较</li>
<li><strong>Date</strong>、<strong>Time</strong>：后边的时间、日期比前面的时间、日期大</li>
</ul>
</blockquote>
<hr>
<blockquote>
<p>向TreeSet中添加元素时的注意点：</p>
<ol>
<li>向 TreeSet 中添加元素时，只有第一个元素无须比较compareTo()方法，后面添加的所有元素都会调用compareTo()方法进行比较。</li>
<li>因为只有相同类的两个实例才会比较大小，所以向 TreeSet 中添加的应该是同一个类的对象。</li>
<li><strong>对于 TreeSet 集合而言，它判断两个对象是否相等的唯一标准是：两个对象通过 compareTo(Object obj) 方法比较返回值</strong>。</li>
<li>当需要把一个对象放入 TreeSet 中，重写该对象对应的 equals() 方法时，应保证该方法与 compareTo(Object obj) 方法有一致的结果：如果两个对象通过equals()方法比较返回 true，则通过 compareTo(Object obj) 方法比较应返回 0。否则，让人难以理解。</li>
</ol>
</blockquote>
<h5 id="TreeSet的定制排序"><a href="#TreeSet的定制排序" class="headerlink" title="TreeSet的定制排序"></a>TreeSet的定制排序</h5><p>  TreeSet的自然排序要求元素所属的类实现Comparable接口，如果元素所属的类没有实现Comparable接口，或不希望按照升序(默认情况)的方式排列元素或希望按照其它属性大小进行排序，则考虑使用定制排序。定制排序，通过Comparator接口来实现。需要重写compare(T o1,T o2)方法。</p>
<blockquote>
<ul>
<li>利用int compare(T o1,T o2)方法，比较o1和o2的大小：如果方法返回正整数，则表示o1大于o2；如果返回0，表示相等；返回负整数，表示o1小于o2。</li>
<li>要实现定制排序，需要将实现Comparator接口的实例作为形参传递给TreeSet的构造器。</li>
<li>此时，仍然只能向TreeSet中添加类型相同的对象。否则发生ClassCastException异常。</li>
<li><strong>使用定制排序判断两个元素相等的标准是：通过Comparator比较两个元素返回了0</strong>。</li>
</ul>
</blockquote>
<h3 id="六、Map接口"><a href="#六、Map接口" class="headerlink" title="六、Map接口"></a>六、Map接口</h3><p>  Map与Collection并列存在。用于保存具有<strong>映射关系</strong>的数据对：key-value。Map 中的 key 和 value 都可以是<strong>任何引用类型</strong>的数据。Map 中的 key 用Set来存放，<strong>不允许重复</strong>，所以key所对应的类，须重写hashCode()和equals()方法。开发中常用String类作为Map的“键”。key 和 value 之间存在单向一对一关系，即通过指定的key 总能找到唯一的、确定的 value。Map接口的常用实现类：<strong>HashMap</strong>、<strong>LinkedHashMap</strong>、<strong>TreeMap</strong>、<strong>HashTable</strong>、<strong>Properties</strong>。其中，<strong>HashMap是 Map 接口使用频率最高的实现类</strong>。</p>
<blockquote>
<ul>
<li><p><strong>HashMap：</strong>作为Map的主要实现类；<strong>线程不安全，效率高</strong>；可以存储null的key和value</p>
<blockquote>
<ul>
<li><strong>LinkedHashMap：</strong>作为HashMap的子类，可以保证在遍历map元素时，按照添加的顺序实现遍历。<strong>原因：</strong>在原有的HashMap底层结构基础上，添加了一对指针，分别指向前后元素，对于频繁的遍历操作，此类执行效率高于HashMap</li>
</ul>
</blockquote>
</li>
<li><p><strong>TreeMap：</strong>保证按照添加的key-value对进行排序，实现排序遍历。此时考虑key的<strong>自然排序</strong>或<strong>定制排序</strong>。底层使用<strong>红黑树</strong></p>
</li>
<li><p><strong>HashTable：</strong>作为古老的实现类；<strong>线程安全，效率低</strong>；不能存储null的key和value</p>
<blockquote>
<ul>
<li><strong>Properties：</strong>作为HashTable的子类，常用来处理配置文件。key和value都是String类型</li>
</ul>
</blockquote>
</li>
</ul>
<p><strong>HashMap的底层：数组+链表  （jdk7及之前）; 数组+链表+红黑树 （jdk 8）</strong></p>
</blockquote>
<h4 id="1、Map结构的理解"><a href="#1、Map结构的理解" class="headerlink" title="1、Map结构的理解"></a>1、Map结构的理解</h4><blockquote>
<ul>
<li>Map中的key：无序的、不可重复的，使用<strong>Set存储</strong>所有的key。<strong>key所在的类要重写equals()和hashCode()方法</strong></li>
<li>Map中的value：无序的、可重复的，使用<strong>Collection存储</strong>所有的value。<strong>value所在的类要重写equals()方法</strong></li>
<li>键值对Entry：key-value构成一个Entry对象。Map中的entry是无序的、不可重复的，使用<strong>Set存储</strong>所有的entry</li>
</ul>
</blockquote>
<h4 id="2、Map接口中的常用方法"><a href="#2、Map接口中的常用方法" class="headerlink" title="2、Map接口中的常用方法"></a>2、Map接口中的常用方法</h4><blockquote>
<p>添加、删除、修改操作：</p>
<ul>
<li>Object put(Object key,Object value)：将指定key-value添加到(或修改)当前map对象中</li>
<li>void putAll(Map m)：将m中的所有key-value对存放到当前map中</li>
<li>Object remove(Object key)：移除指定key的key-value对，并返回value</li>
<li>void clear()：清空当前map中的所有数据</li>
</ul>
<p>元素查询的操作：</p>
<ul>
<li>Object get(Object key)：获取指定key对应的value</li>
<li>Object getOrDefault(Object key, Object defaultValue)：获取指定key对应的value，如果不存在该key，则返回指定的默认值</li>
<li>boolean containsKey(Object key)：是否包含指定的key</li>
<li>boolean containsValue(Object value)：是否包含指定的value</li>
<li>int size()：返回map中key-value对的个数</li>
<li>boolean isEmpty()：判断当前map是否为空</li>
<li>boolean equals(Object obj)：判断当前map和参数对象obj是否相等</li>
</ul>
<p>元视图操作的方法：</p>
<ul>
<li>Set keySet()：返回所有key构成的Set集合</li>
<li>Collection values()：返回所有value构成的Collection集合。<strong>value是可重复无序的，所以用Collection来接收比较合适。为什么不用List呢，因为List有一些与索引相关的操作对于无序的数据来说没啥用。</strong></li>
<li>Set entrySet()：返回所有key-value对构成的Set集合</li>
</ul>
<p>总结：</p>
<blockquote>
<p>添加：put(Object key,Object value)<br>删除：remove(Object key)<br>修改：put(Object key,Object value)<br>查询：get(Object key) &#x2F; getOrDefault(Object key, Object defaultValue)<br>长度：size()<br>遍历：keySet() &#x2F; values() &#x2F; entrySet()</p>
</blockquote>
</blockquote>
<h4 id="3-Map的遍历-keySet-、values-、entrySet"><a href="#3-Map的遍历-keySet-、values-、entrySet" class="headerlink" title="3. Map的遍历 keySet()、values()、entrySet()"></a>3. Map的遍历 keySet()、values()、entrySet()</h4><blockquote>
<ul>
<li>Set keySet()</li>
<li>Collection values()</li>
<li>Set entrySet()</li>
</ul>
</blockquote>
<pre class="language-java" data-language="java"><code class="language-java"><span class="token comment">/*Map的遍历，通过Set keySet(),Collection values(),Set entrySet()方法返回Collection的子接口类型或Collection类型；
 * 然后调用iterator()方法获得迭代器对象后进行遍历。
 */</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MapTest</span> <span class="token punctuation">&#123;</span>
    <span class="token annotation punctuation">@Test</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token class-name">Map</span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"AA"</span><span class="token punctuation">,</span><span class="token number">123</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token number">45</span><span class="token punctuation">,</span><span class="token number">1234</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        map<span class="token punctuation">.</span><span class="token function">put</span><span class="token punctuation">(</span><span class="token string">"BB"</span><span class="token punctuation">,</span><span class="token number">56</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment">//遍历所有的key集：keySet()</span>
        <span class="token class-name">Set</span> set <span class="token operator">=</span> map<span class="token punctuation">.</span><span class="token function">keySet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">Iterator</span> iterator <span class="token operator">=</span> set<span class="token punctuation">.</span><span class="token function">iterator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">while</span><span class="token punctuation">(</span>iterator<span class="token punctuation">.</span><span class="token function">hasNext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
            <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>iterator<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"******************"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment">//遍历所有的value集：values()</span>
        <span class="token class-name">Collection</span> values <span class="token operator">=</span> map<span class="token punctuation">.</span><span class="token function">values</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token class-name">Object</span> obj <span class="token operator">:</span> values<span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
            <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>obj<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"******************"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment">//遍历所有的key-value</span>
        <span class="token comment">//方式一：entrySet()</span>
        <span class="token class-name">Set</span> entrySet <span class="token operator">=</span> map<span class="token punctuation">.</span><span class="token function">entrySet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">Iterator</span> iterator1 <span class="token operator">=</span> entrySet<span class="token punctuation">.</span><span class="token function">iterator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">while</span> <span class="token punctuation">(</span>iterator1<span class="token punctuation">.</span><span class="token function">hasNext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
            <span class="token class-name">Object</span> obj <span class="token operator">=</span> iterator1<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token comment">//entrySet集合中的元素都是entry</span>
            <span class="token class-name">Map<span class="token punctuation">.</span>Entry</span> entry <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">Map<span class="token punctuation">.</span>Entry</span><span class="token punctuation">)</span> obj<span class="token punctuation">;</span>
            <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>entry<span class="token punctuation">.</span><span class="token function">getKey</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"---->"</span> <span class="token operator">+</span> entry<span class="token punctuation">.</span><span class="token function">getValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"******************"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment">//方式二：</span>
        <span class="token class-name">Set</span> keySet <span class="token operator">=</span> map<span class="token punctuation">.</span><span class="token function">keySet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">Iterator</span> iterator2 <span class="token operator">=</span> keySet<span class="token punctuation">.</span><span class="token function">iterator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">while</span><span class="token punctuation">(</span>iterator2<span class="token punctuation">.</span><span class="token function">hasNext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">&#123;</span>
            <span class="token class-name">Object</span> key <span class="token operator">=</span> iterator2<span class="token punctuation">.</span><span class="token function">next</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token class-name">Object</span> value <span class="token operator">=</span> map<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>key<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>key <span class="token operator">+</span> <span class="token string">"====="</span> <span class="token operator">+</span> value<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre>

<h4 id="4、HashMap-类"><a href="#4、HashMap-类" class="headerlink" title="4、HashMap 类"></a>4、HashMap 类</h4><p>  <strong>HashMap是Map接口使用频率最高的实现类</strong>。允许使用null键和null值，与HashSet一样，不保证映射的顺序。所有的key构成的集合是Set，无序的不可重复的，所以key所在的类要重写equals()和hashCode()方法。所有的value构成的集合是Collection，无序的可以重复的，所以value所在的类要重写equals()方法。一个key-value对构成一个entry。所有的entry构成的集合是Set，无序的不可重复的。</p>
<blockquote>
<ul>
<li>HashMap判断两个key相等的标准是：两个key通过equals()方法返回true，同时要求hashCode值也相等</li>
<li>HashMap判断两个value相等的标准是：两个value通过equals()方法返回true</li>
</ul>
</blockquote>
<h5 id="HashMap的底层结构："><a href="#HashMap的底层结构：" class="headerlink" title="HashMap的底层结构："></a>HashMap的底层结构：</h5><table>
<thead>
<tr>
<th>JDK 7</th>
<th>JDK 8</th>
</tr>
</thead>
<tbody><tr>
<td><img src="/posts/b593f441/8.png"></td>
<td><img src="/posts/b593f441/9.png"></td>
</tr>
</tbody></table>
<blockquote>
<p><strong>1.JDK 1.8之前：</strong><br>  HashMap的内部存储结构其实是数组和链表的结合。当实例化一个HashMap时，系统会创建一个长度为Capacity（默认长度为10）的Entry数组Entry[] table，这个长度在哈希表中被称为容量(Capacity)，在这个数组中可以存放元素的位置我们称之为“桶”(bucket)，每个bucket都有自己的索引，系统可以根据索引快速的查找bucket中的元素。每个bucket中存储一个元素，即一个Entry对象，但每一个Entry对象可以带一个引用变量，用于指向下一个元素，因此，在一个桶中，就有可能生成一个Entry链。而且新添加的元素作为链表的head。<br><strong>2.JDK 1.8：</strong><br>  HashMap的内部存储结构变成了数组+链表+树的结合。当实例化一个HashMap时，会初始化initialCapacity和loadFactor，在put第一对映射关系时，系统会创建一个长度为initialCapacity的Node数组，这个长度在哈希表中被称为容量(Capacity)，在这个数组中可以存放元素的位置我们称之为“桶”(bucket)，每个bucket都有自己的索引，系统可以根据索引快速的查找bucket中的元素。每个bucket中存储一个元素，即一个Node对象，但每一个Node对象可以带一个引用变量next，用于指向下一个元素，因此，在一个桶中，就有可能生成一个Node链。也可能是一个一个TreeNode对象，每一个TreeNode对象可以有两个叶子结点left和right，因此，在一个桶中，就有可能生成一个TreeNode树。而新添加的元素作为链表的last，或树的叶子结点。<br><strong>3.HashMap的扩容：</strong><br>  当HashMap中的元素越来越多的时候，hash冲突的几率也就越来越高，因为数组的长度是固定的。所以为了提高查询的效率，就要对HashMap的数组进行扩容，<strong>而在HashMap数组扩容之后，最消耗性能的点就出现了：原数组中的数据必须重新计算其在新数组中的位置，并放进去</strong>，这就是resize。<br>  当HashMap中的元素个数超过数组大小(数组总大小length，不是数组中个数size)&amp;times;loadFactor 时，就会进行数组扩容，loadFactor 的默认值(DEFAULT_LOAD_FACTOR)为0.75，这是一个折中的取值。也就是说，默认情况下，数组大小(DEFAULT_INITIAL_CAPACITY)为16，那么当HashMap中元素个数超过16&amp;times;0.75&#x3D;12（这个值就是代码中的threshold值，也叫做临界值）的时候，就把数组的大小扩展为 2&amp;times;16&#x3D;32，即扩大一倍，然后重新计算每个元素在数组中的位置，而这是一个非常消耗性能的操作，所以<strong>如果我们已经预知HashMap中元素的个数，那么预设元素的个数能够有效的提高HashMap的性能。</strong></p>
</blockquote>
<blockquote>
<p><strong>4.总结：（JDK1.8相较于之前的变化）</strong></p>
<blockquote>
<ul>
<li>HashMap map &#x3D; new HashMap();&#x2F;&#x2F;默认情况下，先不创建长度为16的数组</li>
<li>当首次调用map.put()时，再创建长度为16的数组</li>
<li>数组为Node类型，在jdk7中称为Entry类型</li>
<li>形成链表结构时，新添加的key-value对在链表的尾部（七上八下）</li>
<li>当数组指定索引位置的链表长度&gt;8时，且map中的数组的长度&gt; 64时，此索引位置上的所有key-value对使用红黑树进行存储。</li>
</ul>
</blockquote>
</blockquote>
<h5 id="HashMap源码中的重要常量"><a href="#HashMap源码中的重要常量" class="headerlink" title="HashMap源码中的重要常量"></a>HashMap源码中的重要常量</h5><blockquote>
<ul>
<li>DEFAULT_INITIAL_CAPACITY：HashMap的默认容量，16</li>
<li>MAXIMUM_CAPACITY：HashMap的最大支持容量，2^30</li>
<li>DEFAULT_LOAD_FACTOR：HashMap的默认加载因子 0.75</li>
<li>TREEIFY_THRESHOLD：Bucket中链表长度大于该默认值 8，转化为红黑树</li>
<li>UNTREEIFY_THRESHOLD：Bucket中红黑树存储的Node小于该默认值，转化为链表</li>
<li>MIN_TREEIFY_CAPACITY：桶中的Node被树化时最小的hash表容量 64。（当桶中Node的数量大到需要变红黑树时，若hash表容量小于MIN_TREEIFY_CAPACITY时，此时应执行resize扩容操作。这个MIN_TREEIFY_CAPACITY的值至少是TREEIFY_THRESHOLD的4倍。）</li>
<li>table：存储元素的数组，总是2的n次幂</li>
<li>entrySet：存储具体元素的集</li>
<li>size：HashMap中存储的键值对的数量</li>
<li>modCount：HashMap扩容和结构改变的次数。</li>
<li>threshold：扩容的临界值&#x3D;容量*填充因子 12</li>
<li>loadFactor：填充因子</li>
<li>负载因子的大小，对HashMap有什么影响<blockquote>
<ul>
<li>负载因子的大小<strong>决定了HashMap的数据密度</strong>。</li>
<li>负载因子越大密度越大，发生碰撞的几率越高，数组中的链表越容易长,造成查询或插入时的比较次数增多，性能会下降。</li>
<li>负载因子越小，就越容易触发扩容，数据密度也越小，意味着发生碰撞的几率越小，数组中的链表也就越短，查询和插入时比较的次数也越小，性能会更高。但是会浪费一定的内容空间。而且经常扩容也会影响性能，建议初始化预设大一点的空间。</li>
<li>按照其他语言的参考及研究经验，会考虑将负载因子设置为0.7~0.75，此时平均检索长度接近于常数。</li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
<h5 id="向HashMap中添加元素的过程"><a href="#向HashMap中添加元素的过程" class="headerlink" title="向HashMap中添加元素的过程"></a>向HashMap中添加元素的过程</h5><p>  以IDK7为例，向HashMap中添加entry1(key，value)时，向HashMap中添加entry1(key，value)，需要首先计算entry1中key的哈希值(根据key所在类的hashCode()计算得到)，此哈希值经过处理以后，得到在底层Entry[]数组中要存储的位置i。如果位置i上没有元素，则entry1直接添加成功。如果位置i上已经存在entry2(或还有链表存在的entry3，entry4)，则需要通过循环的方法，依次比较entry1中key和其他的entry。如果彼此hash值不同，则直接添加成功。如果hash值相同，继续比较二者是否equals。如果返回值为true，则使用entry1的value去替换equals为true的entry的value。如果遍历一遍以后，发现所有的equals返回都为false,则entry1仍可添加成功。entry1指向该数组位置上原有的entry元素。</p>
<blockquote>
<p>map.put(key1,value1):<br>首先，调用key1所在类的hashCode()计算key1哈希值，此哈希值经过某种算法计算以后，得到在Entry数组中的存放位置。</p>
<blockquote>
<ul>
<li>如果此位置上的数据为空，此时的key1-value1添加成功。 —&gt;<strong>情况 ①</strong></li>
<li>如果此位置上的数据不为空，(意味着此位置上存在一个或多个数据(以链表形式存在)),比较key1和已经存在的一个或多个数据的哈希值：<blockquote>
<ul>
<li>如果key1的哈希值与已经存在的数据的哈希值都不相同，此时key1-value1添加成功。—&gt;<strong>情况 ②</strong></li>
<li>如果key1的哈希值和已经存在的某一个数据(key2-value2)的哈希值相同，继续比较：调用key1所在类的equals(key2)方法，比较：<blockquote>
<ul>
<li>如果equals()返回false：此时key1-value1添加成功。—&gt;<strong>情况 ③</strong></li>
<li>如果equals()返回true：使用value1替换value2。 —&gt;<strong>情况 ④（修改替换）</strong></li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
<p>  关于情况2和情况3：此时key1-value1和原来的数据以链表的方式存储。在不断的添加过程中，会涉及到扩容问题，当超出临界值(且要存放的位置非空)时，扩容。默认的扩容方式：扩容为原来容量的2倍，并将原有的数据复制过来。<br>  jdk8 相较于jdk7在底层实现方面的不同：</p>
<blockquote>
<ul>
<li>new HashMap()：底层没有创建一个长度为16的数组</li>
<li><strong>jdk 8底层的数组是：Node[],而非Entry[]</strong></li>
<li>首次调用put()方法时，底层创建长度为16的数组</li>
<li>jdk7底层结构只有：数组+链表。jdk8中底层结构：数组+链表+红黑树。<blockquote>
<ul>
<li>形成链表时，七上八下（jdk7:新的元素指向旧的元素。jdk8：旧的元素指向新的元素）</li>
<li>当数组的某一个索引位置上的元素以链表形式存在的数据个数 &gt; 8 且当前数组的长度 &gt; 64时，此时此索引位置上的所数据改为使用红黑树存储。</li>
</ul>
</blockquote>
</li>
</ul>
</blockquote>
</blockquote>
<h4 id="5、LinkedHashMap-类"><a href="#5、LinkedHashMap-类" class="headerlink" title="5、LinkedHashMap 类"></a>5、LinkedHashMap 类</h4><blockquote>
<ul>
<li>LinkedHashMap 是 HashMap 的子类</li>
<li>在HashMap存储结构的基础上，使用了一对双向链表来记录添加元素的顺序</li>
<li>与LinkedHashSet类似，LinkedHashMap 可以维护 Map 的迭代顺序：迭代顺序与 Key-Value 对的插入顺序一致<br><img src="/posts/b593f441/10.png"></li>
<li>LinkedHashMap的其中一个构造函数**LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)**可以通过 accessOrder 设置是否需要按照访问顺序排序，最近访问的元素排在最后，调用put(key,val)和get(key)都算是一次访问。有效利用该点，可以实现LRU缓存算法。</li>
</ul>
</blockquote>
<h4 id="6、TreeMap-类"><a href="#6、TreeMap-类" class="headerlink" title="6、TreeMap 类"></a>6、TreeMap 类</h4><blockquote>
<ul>
<li><p>TreeMap存储 Key-Value 对时，需要根据 key-value 对进行排序。TreeMap 可以保证所有的 Key-Value 对处于有序状态。</p>
</li>
<li><p>向TreeMap中添加key-value，要求key必须是由同一个类创建的对象。因为排序需要同类别对象比较大小。</p>
</li>
<li><p>TreeSet底层使用红黑树结构存储数据</p>
</li>
<li><p>TreeMap 的 Key 的排序：</p>
<blockquote>
<ul>
<li><strong>自然排序：</strong>TreeMap 的所有的 Key 必须实现 Comparable 接口，而且所有的 Key 应该是同一个类的对象，否则将会抛出 ClasssCastException</li>
<li><strong>定制排序：</strong>创建 TreeMap 时，传入一个 Comparator 对象，该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口</li>
</ul>
</blockquote>
</li>
<li><p>TreeMap判断两个key相等的标准：两个key通过compareTo()方法或者compare()方法返回0。</p>
</li>
</ul>
</blockquote>
<h4 id="7、HashTable-类"><a href="#7、HashTable-类" class="headerlink" title="7、HashTable 类"></a>7、HashTable 类</h4><blockquote>
<ul>
<li>Hashtable是个古老的 Map 实现类，JDK1.0就提供了。不同于HashMap，Hashtable是线程安全的。</li>
<li>Hashtable实现原理和HashMap相同，功能相同。底层都使用哈希表结构，查询速度快，很多情况下可以互用。</li>
<li>与HashMap不同，Hashtable 不允许使用 null 作为 key 和 value</li>
<li>与HashMap一样，Hashtable 也不能保证其中 Key-Value 对的顺序</li>
<li>Hashtable判断两个key相等、两个value相等的标准，与HashMap一致。</li>
</ul>
</blockquote>
<h4 id="8、Properties-类"><a href="#8、Properties-类" class="headerlink" title="8、Properties 类"></a>8、Properties 类</h4><blockquote>
<ul>
<li>Properties 类是 Hashtable 的子类，该对象用于处理属性文件</li>
<li>由于属性文件里的 key、value 都是字符串类型，所以 Properties 里的 key 和 value 都是字符串类型</li>
<li>存取数据时，建议使用setProperty(String key,String value)方法和 getProperty(String key)方法</li>
</ul>
</blockquote>
<p>jdbc.properties 文件</p>
<pre class="language-text" data-language="text"><code class="language-text">name=Tom
password=123456</code></pre>

<pre class="language-java" data-language="java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">PropertiesTest</span> <span class="token punctuation">&#123;</span>
    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
        <span class="token class-name">Properties</span> pros <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Properties</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">FileInputStream</span> fis <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>

        <span class="token keyword">try</span> <span class="token punctuation">&#123;</span>
            fis <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FileInputStream</span><span class="token punctuation">(</span><span class="token string">"jdbc.properties"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            pros<span class="token punctuation">.</span><span class="token function">load</span><span class="token punctuation">(</span>fis<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//加载流对应的文件</span>

            <span class="token class-name">String</span> name <span class="token operator">=</span> pros<span class="token punctuation">.</span><span class="token function">getProperty</span><span class="token punctuation">(</span><span class="token string">"name"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token class-name">String</span> password <span class="token operator">=</span> pros<span class="token punctuation">.</span><span class="token function">getProperty</span><span class="token punctuation">(</span><span class="token string">"password"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"name = "</span> <span class="token operator">+</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"password = "</span> <span class="token operator">+</span> password<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token punctuation">&#125;</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">IOException</span> e<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
            e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">&#125;</span> <span class="token keyword">finally</span><span class="token punctuation">&#123;</span>
            <span class="token keyword">if</span> <span class="token punctuation">(</span>fis <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                <span class="token keyword">try</span> <span class="token punctuation">&#123;</span>
                    fis<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">&#125;</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">IOException</span> e<span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
                    e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">&#125;</span>
            <span class="token punctuation">&#125;</span>
        <span class="token punctuation">&#125;</span>
    <span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span></code></pre>

                
            </div>
            <hr/>

            

    <div class="reprint" id="reprint-statement">
        
            <div class="reprint__author">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-user">
                        文章作者:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="/about" rel="external nofollow noreferrer">YangChongZhi</a>
                </span>
            </div>
            <div class="reprint__type">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-link">
                        文章链接:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="http://yczlab.top/posts/b593f441.html">http://yczlab.top/posts/b593f441.html</a>
                </span>
            </div>
            <div class="reprint__notice">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-copyright">
                        版权声明:
                    </i>
                </span>
                <span class="reprint-info">
                    本博客所有文章除特別声明外，均采用
                    <a href="https://creativecommons.org/licenses/by/4.0/deed.zh" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a>
                    许可协议。转载请注明来源
                    <a href="/about" target="_blank">YangChongZhi</a>
                    !
                </span>
            </div>
        
    </div>

    <script async defer>
      document.addEventListener("copy", function (e) {
        let toastHTML = '<span>复制成功，请遵循本文的转载规则</span><button class="btn-flat toast-action" onclick="navToReprintStatement()" style="font-size: smaller">查看</a>';
        M.toast({html: toastHTML})
      });

      function navToReprintStatement() {
        $("html, body").animate({scrollTop: $("#reprint-statement").offset().top - 80}, 800);
      }
    </script>



            <div class="tag_share" style="display: block;">
                <div class="post-meta__tag-list" style="display: inline-block;">
                    
                        <div class="article-tag">
                            
                                <a href="/tags/Java/">
                                    <span class="chip bg-color">Java</span>
                                </a>
                            
                        </div>
                    
                </div>
                <div class="post_share" style="zoom: 80%; width: fit-content; display: inline-block; float: right; margin: -0.15rem 0;">
                    <link rel="stylesheet" type="text/css" href="/libs/share/css/share.min.css">
<div id="article-share">

    
    <div class="social-share" data-sites="twitter,facebook,google,qq,qzone,wechat,weibo,douban,linkedin" data-wechat-qrcode-helper="<p>微信扫一扫即可分享！</p>"></div>
    <script src="/libs/share/js/social-share.min.js"></script>
    

    

</div>

                </div>
            </div>
            
                <style>
    #reward {
        margin: 40px 0;
        text-align: center;
    }

    #reward .reward-link {
        font-size: 1.4rem;
        line-height: 38px;
    }

    #reward .btn-floating:hover {
        box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2), 0 5px 15px rgba(0, 0, 0, 0.2);
    }

    #rewardModal {
        width: 320px;
        height: 350px;
    }

    #rewardModal .reward-title {
        margin: 15px auto;
        padding-bottom: 5px;
    }

    #rewardModal .modal-content {
        padding: 10px;
    }

    #rewardModal .close {
        position: absolute;
        right: 15px;
        top: 15px;
        color: rgba(0, 0, 0, 0.5);
        font-size: 1.3rem;
        line-height: 20px;
        cursor: pointer;
    }

    #rewardModal .close:hover {
        color: #ef5350;
        transform: scale(1.3);
        -moz-transform:scale(1.3);
        -webkit-transform:scale(1.3);
        -o-transform:scale(1.3);
    }

    #rewardModal .reward-tabs {
        margin: 0 auto;
        width: 210px;
    }

    .reward-tabs .tabs {
        height: 38px;
        margin: 10px auto;
        padding-left: 0;
    }

    .reward-content ul {
        padding-left: 0 !important;
    }

    .reward-tabs .tabs .tab {
        height: 38px;
        line-height: 38px;
    }

    .reward-tabs .tab a {
        color: #fff;
        background-color: #ccc;
    }

    .reward-tabs .tab a:hover {
        background-color: #ccc;
        color: #fff;
    }

    .reward-tabs .wechat-tab .active {
        color: #fff !important;
        background-color: #22AB38 !important;
    }

    .reward-tabs .alipay-tab .active {
        color: #fff !important;
        background-color: #019FE8 !important;
    }

    .reward-tabs .reward-img {
        width: 210px;
        height: 210px;
    }
</style>

<div id="reward">
    <a href="#rewardModal" class="reward-link modal-trigger btn-floating btn-medium waves-effect waves-light red">赏</a>

    <!-- Modal Structure -->
    <div id="rewardModal" class="modal">
        <div class="modal-content">
            <a class="close modal-close"><i class="fas fa-times"></i></a>
            <h4 class="reward-title">你的赏识是我前进的动力</h4>
            <div class="reward-content">
                <div class="reward-tabs">
                    <ul class="tabs row">
                        <li class="tab col s6 alipay-tab waves-effect waves-light"><a href="#alipay">支付宝</a></li>
                        <li class="tab col s6 wechat-tab waves-effect waves-light"><a href="#wechat">微 信</a></li>
                    </ul>
                    <div id="alipay">
                        <img src="/medias/reward/alipay.jpg" class="reward-img" alt="支付宝打赏二维码">
                    </div>
                    <div id="wechat">
                        <img src="/medias/reward/wechat.png" class="reward-img" alt="微信打赏二维码">
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
    $(function () {
        $('.tabs').tabs();
    });
</script>

            
        </div>
    </div>

    

    

    

    

    
        <style>
    .valine-card {
        margin: 1.5rem auto;
    }

    .valine-card .card-content {
        padding: 20px 20px 5px 20px;
    }

    #vcomments textarea {
        box-sizing: border-box;
        background: url("/medias/comment_bg.webp") 100% 100% no-repeat;
    }

    #vcomments p {
        margin: 2px 2px 10px;
        font-size: 1.05rem;
        line-height: 1.78rem;
    }

    #vcomments blockquote p {
        text-indent: 0.2rem;
    }

    #vcomments a {
        padding: 0 2px;
        color: #4cbf30;
        font-weight: 500;
        text-decoration: none;
    }

    #vcomments img {
        max-width: 100%;
        height: auto;
        cursor: pointer;
    }

    #vcomments ol li {
        list-style-type: decimal;
    }

    #vcomments ol,
    ul {
        display: block;
        padding-left: 2em;
        word-spacing: 0.05rem;
    }

    #vcomments ul li,
    ol li {
        display: list-item;
        line-height: 1.8rem;
        font-size: 1rem;
    }

    #vcomments ul li {
        list-style-type: disc;
    }

    #vcomments ul ul li {
        list-style-type: circle;
    }

    #vcomments table, th, td {
        padding: 12px 13px;
        border: 1px solid #dfe2e5;
    }

    #vcomments table, th, td {
        border: 0;
    }

    table tr:nth-child(2n), thead {
        background-color: #fafafa;
    }

    #vcomments table th {
        background-color: #f2f2f2;
        min-width: 80px;
    }

    #vcomments table td {
        min-width: 80px;
    }

    #vcomments h1 {
        font-size: 1.85rem;
        font-weight: bold;
        line-height: 2.2rem;
    }

    #vcomments h2 {
        font-size: 1.65rem;
        font-weight: bold;
        line-height: 1.9rem;
    }

    #vcomments h3 {
        font-size: 1.45rem;
        font-weight: bold;
        line-height: 1.7rem;
    }

    #vcomments h4 {
        font-size: 1.25rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    #vcomments h5 {
        font-size: 1.1rem;
        font-weight: bold;
        line-height: 1.4rem;
    }

    #vcomments h6 {
        font-size: 1rem;
        line-height: 1.3rem;
    }

    #vcomments p {
        font-size: 1rem;
        line-height: 1.5rem;
    }

    #vcomments hr {
        margin: 12px 0;
        border: 0;
        border-top: 1px solid #ccc;
    }

    #vcomments blockquote {
        margin: 15px 0;
        border-left: 5px solid #42b983;
        padding: 1rem 0.8rem 0.3rem 0.8rem;
        color: #666;
        background-color: rgba(66, 185, 131, .1);
    }

    #vcomments pre {
        font-family: monospace, monospace;
        padding: 1.2em;
        margin: .5em 0;
        background: #272822;
        overflow: auto;
        border-radius: 0.3em;
        tab-size: 4;
    }

    #vcomments code {
        font-family: monospace, monospace;
        padding: 1px 3px;
        font-size: 0.92rem;
        color: #e96900;
        background-color: #f8f8f8;
        border-radius: 2px;
    }

    #vcomments pre code {
        font-family: monospace, monospace;
        padding: 0;
        color: #e8eaf6;
        background-color: #272822;
    }

    #vcomments pre[class*="language-"] {
        padding: 1.2em;
        margin: .5em 0;
    }

    #vcomments code[class*="language-"],
    pre[class*="language-"] {
        color: #e8eaf6;
    }

    #vcomments [type="checkbox"]:not(:checked), [type="checkbox"]:checked {
        position: inherit;
        margin-left: -1.3rem;
        margin-right: 0.4rem;
        margin-top: -1px;
        vertical-align: middle;
        left: unset;
        visibility: visible;
    }

    #vcomments b,
    strong {
        font-weight: bold;
    }

    #vcomments dfn {
        font-style: italic;
    }

    #vcomments small {
        font-size: 85%;
    }

    #vcomments cite {
        font-style: normal;
    }

    #vcomments mark {
        background-color: #fcf8e3;
        padding: .2em;
    }

    #vcomments table, th, td {
        padding: 12px 13px;
        border: 1px solid #dfe2e5;
    }

    table tr:nth-child(2n), thead {
        background-color: #fafafa;
    }

    #vcomments table th {
        background-color: #f2f2f2;
        min-width: 80px;
    }

    #vcomments table td {
        min-width: 80px;
    }

    #vcomments [type="checkbox"]:not(:checked), [type="checkbox"]:checked {
        position: inherit;
        margin-left: -1.3rem;
        margin-right: 0.4rem;
        margin-top: -1px;
        vertical-align: middle;
        left: unset;
        visibility: visible;
    }
</style>

<div class="card valine-card" data-aos="fade-up">
    <div class="comment_headling" style="font-size: 20px; font-weight: 700; position: relative; padding-left: 20px; top: 15px; padding-bottom: 5px;">
        <i class="fas fa-comments fa-fw" aria-hidden="true"></i>
        <span>评论</span>
    </div>
    <div id="vcomments" class="card-content" style="display: grid">
    </div>
</div>

<script src="/libs/valine/av-min.js"></script>
<script src="/libs/valine/Valine.min.js"></script>
<script>
    new Valine({
        el: '#vcomments',
        appId: 'jJDtz1MXtl9cRxLcrXYvlvhd-9Nh9j0Va',
        appKey: 'UpF6BuVYYhInv6M8vXS0dWRt',
        pageSize: '10',
        notify: 'false' === 'true',
        verify: 'false' === 'true',
        visitor: 'false' === 'true',
        avatar: 'monsterid',
		recordIP: 'true',
		enableQQ: 'true',
		requiredFields: ["nick", "mail"],
        lang: 'zh-cn',
        placeholder: '请开始你的表演吧！\n注意博客留言要求填写昵称、邮箱'
    });
</script>

    

    

    

    

<article id="prenext-posts" class="prev-next articles">
    <div class="row article-row">
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge left-badge text-color">
                <i class="fas fa-chevron-left"></i>&nbsp;上一篇</div>
            <div class="card">
                <a href="/posts/566c9780.html">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/23.jpg" class="responsive-img" alt="Java中的集合工具类Collections">
                        
                        <span class="card-title">Java中的集合工具类Collections</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                              
引言：
Collections工具类可以用来操作Collection，还能用来操作Map。

  Collections 中提供了一系列静态的方法对集合元素进行排序、查询、修改、复制等操作，还提供了对集合对象设置不可变、对集合对象实现
                        
                    </div>
                    <div class="publish-info">
                        <span class="publish-date">
                            <i class="far fa-clock fa-fw icon-date"></i>2021-01-11
                        </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/Java/" class="post-category">
                                    Java
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/Java/">
                        <span class="chip bg-color">Java</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge right-badge text-color">
                下一篇&nbsp;<i class="fas fa-chevron-right"></i>
            </div>
            <div class="card">
                <a href="/posts/74852cbf.html">
                    <div class="card-image">
                        
                        
                        <img src="/medias/featureimages/20.jpg" class="responsive-img" alt="Java中的注解">
                        
                        <span class="card-title">Java中的注解</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                              
引言：
从 JDK5.0开始，Java增加了对元数据(MetaData)的支持，也就是Annotation(注解)


Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理
                        
                    </div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="far fa-clock fa-fw icon-date"></i>2021-01-09
                            </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/categories/Java/" class="post-category">
                                    Java
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/tags/Java/">
                        <span class="chip bg-color">Java</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
    </div>
</article>

</div>



<!-- 代码块功能依赖 -->
<script type="text/javascript" src="/libs/codeBlock/codeBlockFuction.js"></script>

<!-- 代码语言 -->

<script type="text/javascript" src="/libs/codeBlock/codeLang.js"></script>


<!-- 代码块复制 -->

<script type="text/javascript" src="/libs/codeBlock/codeCopy.js"></script>


<!-- 代码块收缩 -->

<script type="text/javascript" src="/libs/codeBlock/codeShrink.js"></script>


    </div>
    <div id="toc-aside" class="expanded col l3 hide-on-med-and-down">
        <div class="toc-widget card" style="background-color: white;">
            <div class="toc-title"><i class="far fa-list-alt"></i>&nbsp;&nbsp;目录</div>
            <div id="toc-content"></div>
        </div>
    </div>
</div>

<!-- TOC 悬浮按钮. -->

<div id="floating-toc-btn" class="hide-on-med-and-down">
    <a class="btn-floating btn-large bg-color">
        <i class="fas fa-list-ul"></i>
    </a>
</div>


<script src="/libs/tocbot/tocbot.min.js"></script>
<script>
    $(function () {
        tocbot.init({
            tocSelector: '#toc-content',
            contentSelector: '#articleContent',
            headingsOffset: -($(window).height() * 0.4 - 45),
            collapseDepth: Number('0'),
            headingSelector: 'h2, h3, h4'
        });

        // modify the toc link href to support Chinese.
        let i = 0;
        let tocHeading = 'toc-heading-';
        $('#toc-content a').each(function () {
            $(this).attr('href', '#' + tocHeading + (++i));
        });

        // modify the heading title id to support Chinese.
        i = 0;
        $('#articleContent').children('h2, h3, h4').each(function () {
            $(this).attr('id', tocHeading + (++i));
        });

        // Set scroll toc fixed.
        let tocHeight = parseInt($(window).height() * 0.4 - 64);
        let $tocWidget = $('.toc-widget');
        $(window).scroll(function () {
            let scroll = $(window).scrollTop();
            /* add post toc fixed. */
            if (scroll > tocHeight) {
                $tocWidget.addClass('toc-fixed');
            } else {
                $tocWidget.removeClass('toc-fixed');
            }
        });

        
        /* 修复文章卡片 div 的宽度. */
        let fixPostCardWidth = function (srcId, targetId) {
            let srcDiv = $('#' + srcId);
            if (srcDiv.length === 0) {
                return;
            }

            let w = srcDiv.width();
            if (w >= 450) {
                w = w + 21;
            } else if (w >= 350 && w < 450) {
                w = w + 18;
            } else if (w >= 300 && w < 350) {
                w = w + 16;
            } else {
                w = w + 14;
            }
            $('#' + targetId).width(w);
        };

        // 切换TOC目录展开收缩的相关操作.
        const expandedClass = 'expanded';
        let $tocAside = $('#toc-aside');
        let $mainContent = $('#main-content');
        $('#floating-toc-btn .btn-floating').click(function () {
            if ($tocAside.hasClass(expandedClass)) {
                $tocAside.removeClass(expandedClass).hide();
                $mainContent.removeClass('l9');
            } else {
                $tocAside.addClass(expandedClass).show();
                $mainContent.addClass('l9');
            }
            fixPostCardWidth('artDetail', 'prenext-posts');
        });
        
    });
</script>

    

</main>




    <footer class="page-footer bg-color">
    
        <link rel="stylesheet" href="/libs/aplayer/APlayer.min.css">
<style>
    .aplayer .aplayer-lrc p {
        
        display: none;
        
        font-size: 12px;
        font-weight: 700;
        line-height: 16px !important;
    }

    .aplayer .aplayer-lrc p.aplayer-lrc-current {
        
        display: none;
        
        font-size: 15px;
        color: #42b983;
    }

    
    .aplayer.aplayer-fixed.aplayer-narrow .aplayer-body {
        left: -66px !important;
    }

    .aplayer.aplayer-fixed.aplayer-narrow .aplayer-body:hover {
        left: 0px !important;
    }

    
</style>
<div class="">
    
    <div class="row">
        <meting-js class="col l8 offset-l2 m10 offset-m1 s12"
                   server="netease"
                   type="playlist"
                   id="7565528433"
                   fixed='true'
                   autoplay='false'
                   theme='#42b983'
                   loop='all'
                   order='random'
                   preload='auto'
                   volume='0.4'
                   list-folded='true'
        >
        </meting-js>
    </div>
</div>

<script src="/libs/aplayer/APlayer.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js"></script>

    
    <div class="container row center-align" style="margin-bottom: 15px !important;">
        <div class="col s12 m8 l8 copy-right">
            Copyright&nbsp;&copy;
            
                <span id="year">2019-2024</span>
            
            <span id="year">2019</span>
            <a href="/about" target="_blank">YangChongZhi</a>
            |&nbsp;Powered by&nbsp;<a href="https://hexo.io/" target="_blank">Hexo</a>
            |&nbsp;Theme&nbsp;<a href="https://github.com/blinkfox/hexo-theme-matery" target="_blank">Matery</a>
            <br>
            
            &nbsp;<i class="fas fa-chart-area"></i>&nbsp;站点总字数:&nbsp;<span
                class="white-color">236.5k</span>&nbsp;字
            
            
            
            
            
            
            <span id="busuanzi_container_site_pv">
                |&nbsp;<i class="far fa-eye"></i>&nbsp;总访问量:&nbsp;<span id="busuanzi_value_site_pv"
                    class="white-color"></span>&nbsp;次
            </span>
            
            
            <span id="busuanzi_container_site_uv">
                |&nbsp;<i class="fas fa-users"></i>&nbsp;总访问人数:&nbsp;<span id="busuanzi_value_site_uv"
                    class="white-color"></span>&nbsp;人
            </span>
            
            <br>
            
            <span id="sitetime">载入运行时间...</span>
            <script>
                function siteTime() {
                    var seconds = 1000;
                    var minutes = seconds * 60;
                    var hours = minutes * 60;
                    var days = hours * 24;
                    var years = days * 365;
                    var today = new Date();
                    var startYear = "2019";
                    var startMonth = "6";
                    var startDate = "28";
                    var startHour = "0";
                    var startMinute = "0";
                    var startSecond = "0";
                    var todayYear = today.getFullYear();
                    var todayMonth = today.getMonth() + 1;
                    var todayDate = today.getDate();
                    var todayHour = today.getHours();
                    var todayMinute = today.getMinutes();
                    var todaySecond = today.getSeconds();
                    var t1 = Date.UTC(startYear, startMonth, startDate, startHour, startMinute, startSecond);
                    var t2 = Date.UTC(todayYear, todayMonth, todayDate, todayHour, todayMinute, todaySecond);
                    var diff = t2 - t1;
                    var diffYears = Math.floor(diff / years);
                    var diffDays = Math.floor((diff / days) - diffYears * 365);
                    var diffHours = Math.floor((diff - (diffYears * 365 + diffDays) * days) / hours);
                    var diffMinutes = Math.floor((diff - (diffYears * 365 + diffDays) * days - diffHours * hours) /
                        minutes);
                    var diffSeconds = Math.floor((diff - (diffYears * 365 + diffDays) * days - diffHours * hours -
                        diffMinutes * minutes) / seconds);
                    if (startYear == todayYear) {
                        document.getElementById("year").innerHTML = todayYear;
                        document.getElementById("sitetime").innerHTML = "本站已安全运行 " + diffDays + " 天 " + diffHours +
                            " 小时 " + diffMinutes + " 分钟 " + diffSeconds + " 秒";
                    } else {
                        document.getElementById("year").innerHTML = startYear + " - " + todayYear;
                        document.getElementById("sitetime").innerHTML = "本站已安全运行 " + diffYears + " 年 " + diffDays +
                            " 天 " + diffHours + " 小时 " + diffMinutes + " 分钟 " + diffSeconds + " 秒";
                    }
                }
                setInterval(siteTime, 1000);
            </script>
            
            <br>
            
            <span id="icp"><img src="/medias/icp.png" style="vertical-align: text-bottom;" />
                <a href="http://beian.miit.gov.cn/" target="_blank">渝ICP备2021001798号-1</a>
            </span>
            
        </div>
        <div class="col s12 m4 l4 social-link social-statis">
    <a href="https://github.com/yczlab" class="tooltipped" target="_blank" data-tooltip="访问我的GitHub" data-position="top" data-delay="50">
        <i class="fab fa-github"></i>
    </a>



    <a href="https://gitee.com/yczlab" class="tooltipped" target="_blank" data-tooltip="访问我的码云" data-position="top" data-delay="50">
        <i class="fab fa-github"></i>
    </a>



    <a href="mailto:2685733832@qq.com" class="tooltipped" target="_blank" data-tooltip="邮件联系我" data-position="top" data-delay="50">
        <i class="fas fa-envelope-open"></i>
    </a>







    <a href="tencent://AddContact/?fromId=50&fromSubId=1&subcmd=all&uin=2685733832" class="tooltipped" target="_blank" data-tooltip="QQ联系我: 2685733832" data-position="top" data-delay="50">
        <i class="fab fa-qq"></i>
    </a>



    <a href="tencent://AddContact/?fromId=50&fromSubId=1&subcmd=all&uin=2685733832" class="tooltipped" target="_blank" data-tooltip="微信联系我: yczlab" data-position="top" data-delay="50">
        <i class="fab fa-weixin"></i>
    </a>



    <a href="https://weibo.com/yczlab" class="tooltipped" target="_blank" data-tooltip="关注我的微博: https://weibo.com/yczlab" data-position="top" data-delay="50">
        <i class="fab fa-weibo"></i>
    </a>



    <a href="https://www.zhihu.com/people/yczlab" class="tooltipped" target="_blank" data-tooltip="关注我的知乎: https://www.zhihu.com/people/yczlab" data-position="top" data-delay="50">
        <i class="fab fa-zhihu1">知</i>
    </a>



</div>
    </div>
</footer>

<div class="progress-bar"></div>


    <!-- 搜索遮罩框 -->
<div id="searchModal" class="modal">
    <div class="modal-content">
        <div class="search-header">
            <span class="title"><i class="fas fa-search"></i>&nbsp;&nbsp;搜索</span>
            <input type="search" id="searchInput" name="s" placeholder="请输入搜索的关键字"
                   class="search-input">
        </div>
        <div id="searchResult"></div>
    </div>
</div>

<script type="text/javascript">
$(function () {
    var searchFunc = function (path, search_id, content_id) {
        'use strict';
        $.ajax({
            url: path,
            dataType: "xml",
            success: function (xmlResponse) {
                // get the contents from search data
                var datas = $("entry", xmlResponse).map(function () {
                    return {
                        title: $("title", this).text(),
                        content: $("content", this).text(),
                        url: $("url", this).text()
                    };
                }).get();
                var $input = document.getElementById(search_id);
                var $resultContent = document.getElementById(content_id);
                $input.addEventListener('input', function () {
                    var str = '<ul class=\"search-result-list\">';
                    var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
                    $resultContent.innerHTML = "";
                    if (this.value.trim().length <= 0) {
                        return;
                    }
                    // perform local searching
                    datas.forEach(function (data) {
                        var isMatch = true;
                        var data_title = data.title.trim().toLowerCase();
                        var data_content = data.content.trim().replace(/<[^>]+>/g, "").toLowerCase();
                        var data_url = data.url;
                        data_url = data_url.indexOf('/') === 0 ? data.url : '/' + data_url;
                        var index_title = -1;
                        var index_content = -1;
                        var first_occur = -1;
                        // only match artiles with not empty titles and contents
                        if (data_title !== '' && data_content !== '') {
                            keywords.forEach(function (keyword, i) {
                                index_title = data_title.indexOf(keyword);
                                index_content = data_content.indexOf(keyword);
                                if (index_title < 0 && index_content < 0) {
                                    isMatch = false;
                                } else {
                                    if (index_content < 0) {
                                        index_content = 0;
                                    }
                                    if (i === 0) {
                                        first_occur = index_content;
                                    }
                                }
                            });
                        }
                        // show search results
                        if (isMatch) {
                            str += "<li><a href='" + data_url + "' class='search-result-title'>" + data_title + "</a>";
                            var content = data.content.trim().replace(/<[^>]+>/g, "");
                            if (first_occur >= 0) {
                                // cut out 100 characters
                                var start = first_occur - 20;
                                var end = first_occur + 80;
                                if (start < 0) {
                                    start = 0;
                                }
                                if (start === 0) {
                                    end = 100;
                                }
                                if (end > content.length) {
                                    end = content.length;
                                }
                                var match_content = content.substr(start, end);
                                // highlight all keywords
                                keywords.forEach(function (keyword) {
                                    var regS = new RegExp(keyword, "gi");
                                    match_content = match_content.replace(regS, "<em class=\"search-keyword\">" + keyword + "</em>");
                                });

                                str += "<p class=\"search-result\">" + match_content + "...</p>"
                            }
                            str += "</li>";
                        }
                    });
                    str += "</ul>";
                    $resultContent.innerHTML = str;
                });
            }
        });
    };

    searchFunc('/search.xml', 'searchInput', 'searchResult');
});
</script>

    <!-- 回到顶部按钮 -->
<div id="backTop" class="top-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#!">
        <i class="fas fa-arrow-up"></i>
    </a>
</div>


    <script src="/libs/materialize/materialize.min.js"></script>
    <script src="/libs/masonry/masonry.pkgd.min.js"></script>
    <script src="/libs/aos/aos.js"></script>
    <script src="/libs/scrollprogress/scrollProgress.min.js"></script>
    <script src="/libs/lightGallery/js/lightgallery-all.min.js"></script>
    <script src="/js/matery.js"></script>

    <!-- Baidu Analytics -->

    <!-- Baidu Push -->

<script>
    (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        } else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();
</script>

    
    <script src="/libs/others/clicklove.js" async="async"></script>
    
    
    <script async src="/libs/others/busuanzi.pure.mini.js"></script>
    

    
        <script src="//code.tidio.co/ef3vil8uaqrvp7giqeg545xldzmymqss.js"></script>
    

    

	
    
    <script type="text/javascript" color="0,0,255"
        pointColor="0,0,255" opacity='0.5'
        zIndex="-1" count="99"
        src="/libs/background/canvas-nest.js"></script>
    

    
    
    <script type="text/javascript" size="150" alpha='0.6'
        zIndex="-1" src="/libs/background/ribbon-refresh.min.js" async="async"></script>
    

    
    <script type="text/javascript" src="/libs/background/ribbon-dynamic.js" async="async"></script>
    

    
    <script src="/libs/instantpage/instantpage.js" type="module"></script>
    
	
	<script type="text/javascript">
	var OriginTitile = document.title,st;
	document.addEventListener("visibilitychange", function () {
		document.hidden ? (document.title = "Σ(っ °Д °;)っ我隐藏了！", clearTimeout(st)) : (document.title="(๑•̀ㅂ•́) ✧被发现了！", st=setTimeout(function () {document.title = OriginTitile}, 3e3))
	});
	</script>
	
	<!-- 背景樱花飘落特效 -->
	
	
	<!-- 背景雪花飘落特效 -->
	
	
	<!-- 数字雨特效 -->
	
		<script type="text/javascript">
		//只在桌面版网页启用特效
		var windowWidth = $(window).width();
		if (windowWidth > 768) {
			document.write('<canvas id="digitalrain" width="1440" height="900" style="position:fixed; z-index:-2; right:0px; bottom:0px; min-width:100%; min-height:100%; height:auto; width:auto;"><\/canvas>');
			document.write('<script type="text/javascript" src="/js/digitalrain.js"><\/script>');
		}
		</script>
	

</body>

</html>
